Explanation of current code
case 1 is a legal way to initialise s1, with 'a' going into [0], 'p' into [1] and [2], 'l' into [3], 'e' into [4] and the rest set to 0 (ASCII NUL - see http://en.wikipedia.org/wiki/ASCII).
case 2 attempts to assign one array to another (of a different size as per the message), which isn't legal in C++. You should use strcpy(s1, "apple") to do this, though it differs slightly in behaviour: it will only set s1[5] to 0/NUL, with [6] onwards unaffected (if s1 is on the stack or heap they'll be uninitialised and reading from them will be undefined behaviour). Most things you'd want to do with s1 won't benefit from initialisation of [6] onwards....
An intuitive alternative: `std::string`
Perhaps the best approach is to switch to std::string, which works more intuitively (you'll have to #include <string> atop your program). The syntax for case 1 will be slightly different though: either std::string s1 = "apple";, or - if you have a C++11 compiler - std::string s1 { "apple" };.
Writable buffers versus pointers to string literals
Note too that in your question, char s1[100] creates an array of 100 characters that you can read and write to, and you're then copying from a read-only ("const") string literal into that writable buffer. If you just want to keep track of the text (e.g. that it's "apple" as opposed to say "orange" which might be copied into s1 later) without needing to modify the text further, you can use a const char* to store the address of the string literal:
const char* p_s1 = "apple";
if (f()) p_s1 = "orange";
std::cout << "go eat an " << p_s1 << '\n';
As an example of the const nature of string literals, with the const char* p_s1 above you can't modify the pointed-to string literals as in:
#include <cctype>
...
p_s1[0] = std::toupper(p_s1[0]); // oops! p_s1[0] inside string literal - mustn't write
Whereas if you'd stuck with char s1[100]; you could do:
s1[0] = std::toupper(s1[0]); // ok